package com.chocho.javacompileserver.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Arrays;

public class ConsoleOutputCapturer {

    //字节数组输出流
    private ByteArrayOutputStream baos;
    //打印流：内存--->输出
    private PrintStream previous;
    //捕获标志
    private boolean capturing;

//    public static void main(String[] args) {
//        ConsoleOutputCapturer capturer = new ConsoleOutputCapturer();
//        capturer.start();
//        System.out.println("测试下捕捉控制台");
//        System.out.println(capturer.stop());
//    }

    public void start() {
        if (capturing) {
            return;
        }
        capturing = true;
        //系统标志输出流PrintStream
        previous = System.out;
        baos = new ByteArrayOutputStream();
        //将所有输出包装到内部类
        OutputStream outputStreamCombiner = new OutputStreamCombiner(Arrays.asList(previous, baos));
        PrintStream custom = new PrintStream(outputStreamCombiner);
        //将字节流与标准输出设置为系统输出
        System.setOut(custom);
    }

    public String stop() {
        if (!capturing) {
            return "";
        }
        //将PrintStream设置为系统输出
        System.setOut(previous);
        //从字节流获取数据
        String capturedValue = baos.toString();
        baos = null;
        previous = null;
        capturing = false;
        return capturedValue;
    }

    //内部类
    private static class OutputStreamCombiner extends OutputStream {
        //输出流集合
        private List<OutputStream> outputStreams;

        public OutputStreamCombiner(List outputStreams) {
            this.outputStreams = outputStreams;
        }

        @Override
        public void write(int b) throws IOException {
            for (OutputStream os : outputStreams) {
                os.write(b);
            }
        }

        @Override
        public void flush() throws IOException {
            for (OutputStream os : outputStreams) {
                os.flush();
            }
        }

        @Override
        public void close() throws IOException {
            for (OutputStream os : outputStreams) {
                os.close();
            }
        }
    }
}